package cn.com.zcode.user.control;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.util.WebUtils;

import cn.com.zcode.core.control.BaseActionSupport;
import cn.com.zcode.core.util.HttpReqUtil;
import cn.com.zcode.core.util.StringUtil;
import cn.com.zcode.user.model.InviteCode;
import cn.com.zcode.user.model.LoginInfo;
import cn.com.zcode.user.model.User;
import cn.com.zcode.user.service.UserService;
import cn.com.zcode.user.util.UserUtil;

public class UserAction extends BaseActionSupport<UserService> {
	private static final long serialVersionUID = 1L;
	private static Logger logger = Logger.getLogger(UserAction.class);
	private User user;
	private String inviteCode;
	private InviteCode code;
	private boolean autoLogin;
	private String url = "";
	
//
//	public String login() {
//
//		if (user != null) {
//			String username = user.getUsername();
//			String password = user.getPassword();
//			UsernamePasswordToken token = new UsernamePasswordToken(username, password);
//			token.setRememberMe(false);
//			logger.info("为了验证登录用户而封装的token为" + ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
//			// 获取当前的Subject
//			Subject currentUser = SecurityUtils.getSubject();
//			try {
//				// 在调用了login方法后,SecurityManager会收到AuthenticationToken,并将其发送给已配置的Realm执行必须的认证检查
//				// 每个Realm都能在必要时对提交的AuthenticationTokens作出反应
//				// 所以这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中,具体验证方式详见此方法
//				logger.info("对用户[" + username + "]进行登录验证..验证开始");
//				currentUser.login(token);
//				logger.info("对用户[" + username + "]进行登录验证..验证通过");
//			} catch (UnknownAccountException uae) {
//				logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");
//				this.addActionError("未知账户");
//			} catch (IncorrectCredentialsException ice) {
//				logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");
//				this.addActionError("密码不正确");
//			} catch (LockedAccountException lae) {
//				logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");
//				this.addActionError("账户已锁定");
//			} catch (ExcessiveAttemptsException eae) {
//				logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");
//				this.addActionError("用户名或密码错误次数过多");
//			} catch (AuthenticationException ae) {
//				// 通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景
//				logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");
//				ae.printStackTrace();
//				this.addActionError("用户名或密码不正确");
//			}
//			// 验证是否登录成功
//			if (currentUser.isAuthenticated()) {
//				logger.info("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");
//				HttpServletRequest request = this.getRequest();
//				boolean isFromMobile = HttpReqUtil.isFromMobile(request);
//				this.user = this.getSessionAttribute(User.SESSION_USER, User.class);
//				user.setFromMobile(isFromMobile);
//				String ip = UserUtil.getUserIp(request);
//				LoginInfo logininfo = new LoginInfo(user, ip);
//				
//				this.service.addLoginInfo(logininfo);
//				return SUCCESS;
//			} else {
//				token.clear();
//			}
//
//
//		}
//		return LOGIN;
//	}

	public String loginOut() {
		User user = this.getSessionAttribute(User.SESSION_USER, User.class);
		this.service.destroyUser(user);
		Subject currentUser = SecurityUtils.getSubject();
		currentUser.logout();
		logger.info("login out:" + user);
		return SUCCESS;
	}

	public String registInit() {
		return INPUT;
	}

	public String regist() {
		if (user == null) {
			return INPUT;
		} else {
			user.setRegistIp(UserUtil.getUserIp(this.getRequest()));
			service.addUser(user, inviteCode);
			this.addAttribute("justRegist", true);
		}
		return SUCCESS;
	}

	public void validateRegist() {
		super.validate();
		if (inviteCode == null || !service.getInviteCode(inviteCode)) {
			this.addFieldError("inviteCode", "邀请码无效");
		} else if (user != null) {
			User reUser = service.getUserByName(user.getUsername());
			if (reUser != null) {
				this.addFieldError("user.username", "用户名重复");
			}
		}
	}

	public String profile() {
		if (this.user == null) {
			User user = this.getSessionAttribute(User.SESSION_USER, User.class);
			this.user = this.service.getUserById(user.getId());
			return INPUT;
		} else {
			User ouser = this.service.getUserById(user.getId());
			ouser.setNickname(user.getNickname());
			ouser.setEmail(user.getEmail());
			String pwd = user.getPassword();
			if (pwd != null && !(pwd = pwd.trim()).isEmpty()) {
				ouser.setPassword(user.getPassword());
			}
			this.service.saveUser(ouser);
			this.addAttribute("updated", true);
			return SUCCESS;
		}
	}

	public String invite() {
		List<InviteCode> list = this.service.listInviteCodes();
		this.addAttribute("codes", list);

		return SUCCESS;
	}

	public String generInvite() {

		String inviteCode = StringUtil.getMd5Value(System.currentTimeMillis() + "");
		inviteCode = inviteCode.substring(inviteCode.length() - 6);
		User user = this.getSessionAttribute(User.SESSION_USER, User.class);
		this.code = new InviteCode();
		code.setOwner(user.getId());
		code.setEmail(this.user.getEmail());
		code.setCode(inviteCode);
		this.service.addInviteCode(this.code);

		return SUCCESS;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getInviteCode() {
		return inviteCode;
	}

	public void setInviteCode(String inviteCode) {
		this.inviteCode = inviteCode;
	}

	public InviteCode getCode() {
		return code;
	}

	public void setCode(InviteCode code) {
		this.code = code;
	}

	public boolean isAutoLogin() {
		return autoLogin;
	}

	public void setAutoLogin(boolean autoLogin) {
		this.autoLogin = autoLogin;
	}

}
